//
//  Timer+Extension.swift
//  Test
//
//  Created by ZWJY on 2021/8/20.
//

import Foundation
import UIKit


// MARK: - timer 作为属性，防止循环引用
//timer 作为属性，会被强持有，target：会强持有self, 造成循环应用
//自身作为代理，打破循环
public extension Timer {
    
    class func scheduledTimerWithTimeInterval(interval: TimeInterval, repeats: Bool, block: @escaping (Timer)->()) -> Timer{
        return Timer.scheduledTimer(timeInterval: interval, target: self, selector: #selector(action(sender:)), userInfo: block, repeats: repeats)
    }
    
    @objc class func action(sender: Timer){
        guard let block = sender.userInfo as? (Timer)->() else { return }
        block(sender)
    }
    
    /*
     使用
     self.timer = Timer.scheduledTimerWithTimeInterval(interval: 60.0, repeats: true, block: { [weak self] blockTimer in
     guard let self = self else{return}
     
     })
     RunLoop.current.add(self.timer!, forMode: RunLoop.Mode.common) // scrollView中 NSRunLoopCommonModes
     */
}

// MARK: - 倒计时（时分秒、验证码）
public class CountDowmTool {

    /*
     // 声明属性，保证生命周期
     var countDown: CountDowmTool?

     countDown = CountDowmTool.init(timeInterval: 10, waitCallBack: {[weak self] time in
         guard let self = self else { return }

     }, completionCallBack: {[weak self] in
         guard let self = self else { return }

     })
     */

    
    /// 定时器
    var timer: Timer?
    
    /// 验证码倒计时
    /// - Parameters:
    ///   - timeInterval: 时间（秒）
    ///   - waitCallBack: 倒计时
    ///   - completionCallBack: 结束
    convenience init(timeInterval: TimeInterval, waitCallBack: @escaping (String) -> (), completionCallBack: @escaping () -> ()) {
        self.init()
        
        var time = timeInterval
        timerRelease()
        timer = Timer.scheduledTimerWithTimeInterval(interval: 1, repeats: true, block: {[weak self] _ in
            guard let self = self else {return}
            time -= 1
            if time == 0 {
                completionCallBack()
                self.timerRelease()
            }else {
                waitCallBack(String(Int(time)))
            }
        })
        
        RunLoop.current.add(timer!, forMode: RunLoop.Mode.commonModes)
        timer?.fire()
    }
    
    /// 天-时-分-秒倒计时
    /// - Parameters:
    ///   - timeInterval: 时间（秒）
    ///   - waitCallBack: 倒计时
    convenience init(time: Int, waitCallBack: @escaping (String, String, String, String) -> (), completionCallBack: (() -> ())? = nil) {
        self.init()
        
        var timeInterval = time
        timerRelease()
        timer = Timer.scheduledTimerWithTimeInterval(interval: 1, repeats: true, block: {[weak self] _ in
            guard let self = self else {return}
            timeInterval -= 1
            let day = self.dayString(timeInterval)
            let hour = self.hourString(timeInterval)
            let min = self.minutesString(timeInterval)
            let second = self.secondString(timeInterval)
            waitCallBack(day, hour, min, second)
            if time == 0 {
                completionCallBack?()
                self.timerRelease()
            }
        })
        
        RunLoop.current.add(timer!, forMode: RunLoop.Mode.commonModes)
        timer?.fire()
    }
    
    //对象销毁释放
    deinit {
        timerRelease()
    }
    
    /// 每次创建前，释放已存在的定时器
    private func timerRelease() {
        timer?.invalidate()
        timer = nil
    }
    
    private func dayString(_ interval: Int) -> String {
        let days = (interval)/(3600 * 24)
        let timeString  = String(format: "%02lu", days)
        return timeString
    }
    
    //小时计算
    private func hourString(_ interval: Int) -> String {
        let hours = (interval)%(3600 * 24) / 3600
        let timeString  = String(format: "%02lu", hours)
        return timeString
    }
    
    /// 根据需求修改： 获取分钟, （如，1: 30, 计算成2分钟）
    private func minutesString(_ interval: Int) -> String {
        //分钟计算
        let minutes = (interval)%3600/60 + 1;
        let timeString  = String(format: "%02lu", minutes)
        return timeString
    }
    
    //秒计算
    private func secondString(_ interval: Int) -> String {
        let second = (interval)%60;
        let timeString  = String(format: "%02lu", second)
        return timeString
    }
}
